import { GameData, Levels } from "../Data/GameData";
import { BlockType, CardGameState, PosType } from "../Data/GameEnum";
import Grid from "../Game/Grid";
import UIManager from "../Manager/UIManager";
import GamePanel from "../UI/GamePanel";
import Block from "../Game/Block";
import BlockGroup from "../Game/BlockGroup";
import { ArrayUtils, randomRangeInt } from "../utils/ccUtils";
import Card from "../Game/Card";
import AssetsManager from "../Manager/AssetsManager";
import Board from "../Game/Board";
import CommonFunction from "../utils/CommonFunction";

const { ccclass, property } = cc._decorator;

@ccclass
export default class CardFunctions {
    /** 创建格子 */
    static CreateGrid(_id: number, x: number, y: number): Grid {
        const node: cc.Node = cc.instantiate(AssetsManager.Prefabs.Grid);
        const scrGrid: Grid = node.getComponent(Grid);
        scrGrid.init(_id, x, y);
        UIManager.Instance.Root_grid.addChild(node);
        return scrGrid;
    }

    /** 创建牌组 */
    static CreateBlock(_blockType: BlockType, _posType: PosType, _x: number, _y: number, _point: number, _color: number): Block {
        const node: cc.Node = cc.instantiate(AssetsManager.Prefabs.Block);
        const block: Block = node.getComponent(Block);
        GamePanel.Instance.GeneratePoint_blook_list[_x].addChild(node);
        block.init(_blockType, _posType, _x, _y, _point, _color);

        // (_blockType: BlockType, _posType: PosType, _x: number, _y: number, _point: number, _color: number)
        return block;
    }

    /** 创建牌组 */
    static CreateBlockGroup(_x: number, _y: number, _id, _color: number, posType: PosType): BlockGroup {
        const node: cc.Node = cc.instantiate(AssetsManager.Prefabs.BlockGroup);
        const blockGroup: BlockGroup = node.getComponent(BlockGroup);
        GamePanel.Instance.GeneratePoint_blook_list[_x].addChild(node);
        blockGroup.init(_x, _y, _id, _color, posType);
        GameData.arrCardGroups.push(blockGroup);
        return blockGroup;
    }

    // tetrisType
    static 随机创建一个BlockGroup(index) {
        // return
        // console.log("Levels[GameData.CurrentLevel]", Levels[GameData.CurrentLevel]);
        // console.log("Levels[GameData.CurrentLevel]", Levels[GameData.CurrentLevel].d);
        // console.log("Levels[GameData.CurrentLevel]", Levels[GameData.CurrentLevel].u);
        // console.log("Levels[GameData.CurrentLevel]", Levels[GameData.CurrentLevel].m);
        // let Level_data = Levels[GameData.CurrentLevel].d;
        
        let Level_data = GameData.Get_LevelData_down();

        if (GameData.currentBlockGroupCreateIndex >= Level_data.length) {
            return;
        }

        let item_data = Level_data[GameData.currentBlockGroupCreateIndex];
        console.log("item_data", item_data);

        let x = index;
        let y = -1;
        // let id = CardFunctions.GetRandomId();
        let id = item_data.c;
        // let tetrisType = CardFunctions.Get_tetrisType();
        let tetrisType = item_data.t;
        let posType = PosType.下面操作台中;
        CardFunctions.CreateBlockGroup(x, y, id, tetrisType, posType);

        GameData.currentBlockGroupCreateIndex++;
    }

    /** 创建Card */
    static CreateCard(_x: number, _y: number, _id: number, _board: Board): Card {
        const node: cc.Node = cc.instantiate(AssetsManager.Prefabs.Card);
        const card: Card = node.getComponent(Card);
        UIManager.Instance.Root_grid.addChild(node);
        card.Init(_x, _y, _id, _board);
        GameData.arrCards.push(card);
        return card;
    }

    /** 创建Board */
    static CreateBoard(_x: number, _y: number, layer: number, _layout: any, _cardList: any): Board {
        const node: cc.Node = cc.instantiate(AssetsManager.Prefabs.Board);
        const board: Board = node.getComponent(Board);
        UIManager.Instance.Root_board.addChild(node);
        board.Init(_x, _y, layer, _layout, _cardList);
        GameData.arrBoard.push(board);
        return board;
    }

    static GetGrid(x: number, y: number) {
        if (GameData.arrGrids[x] && GameData.arrGrids[x][y]) {
            return GameData.arrGrids[x][y];
        }

        return null;
    }

    static Get_arrCardGroups() {
        return GameData.arrCardGroups;
    }

    static Get_arrCardGroup_grid() {
        const arr = GameData.arrCardGroups.filter(number => number.posType === PosType.方格中);
        return arr;
    }

    /** 获取随机颜色 */
    static GetRandomId() {
        // let id: number = randomRangeInt(0, 12);
        let id: number = randomRangeInt(0, 3);
        return id;
    }

    /** 获取俄罗斯方块类型 */
    static Get_tetrisType() {
        // let id: number = randomRangeInt(0, 9);
        // let id: number = 0;
        let id: number = randomRangeInt(0, 3);

        return id;
    }

    /** 获取随机颜色 */
    static GetRandomColor() {
        let color: number = randomRangeInt(0, 4);
        return color;
    }

    /** 获取随机点数 */
    static GetRandomPoint() {
        let point: number = randomRangeInt(1, 6 + 1);

        return point;
    }


    // 获取Item
    static GetItem(arr, x: number, y: number) {
        if (arr[x] && arr[x][y]) {
            return arr[x][y];
        }

        return null;
    }

    // 
    static GetCanPlceTrueGridList() {
        let list = [];

        for (let x = 0; x < GameData.col; x++) {
            for (let y = 0; y < GameData.row; y++) {
                const grid_0: Grid = CardFunctions.GetGrid(x, y);
                if (grid_0.canPlace) {
                    list.push(grid_0);
                }
            }
        }

        return list;
    }

    // 
    static SetAllGridCanPlaceByBlock(block_target: Block) {
        for (let x = 0; x < GameData.col; x++) {
            for (let y = 0; y < GameData.row; y++) {
                const grid_0: Grid = CardFunctions.GetGrid(x, y);
                if (grid_0.block) {
                    grid_0.canPlace = false;
                }

                let up: Grid = CardFunctions.GetGrid(x, y + 1);
                let down: Grid = CardFunctions.GetGrid(x, y - 1);
                let left: Grid = CardFunctions.GetGrid(x - 1, y);
                let right: Grid = CardFunctions.GetGrid(x + 1, y);

                let array = [up, down, left, right];
                for (let index = 0; index < array.length; index++) {
                    const grid_4: Grid = array[index];
                    if (block_target && grid_4 && grid_4.block) {
                        if (block_target.color !== grid_4.block.color && block_target.point !== grid_4.block.point) {
                            grid_0.canPlace = false;
                        }
                    }
                }
            }
        }
    }

    static RefreshAllGridCanPlace() {
        for (let x = 0; x < GameData.col; x++) {
            for (let y = 0; y < GameData.row; y++) {
                const grid_0: Grid = CardFunctions.GetGrid(x, y);
                if (grid_0) {
                    grid_0.RefreshPlace();
                }
            }
        }
    }

    static SetAllGridCanPlaceForce(active: boolean) {
        for (let x = 0; x < GameData.col; x++) {
            for (let y = 0; y < GameData.row; y++) {
                const grid_0: Grid = CardFunctions.GetGrid(x, y);
                if (grid_0) {
                    grid_0.canPlace = active;
                    grid_0.RefreshPlace();
                }
            }
        }
    }

    // 
    static AllGridSelect(active: boolean) {
        for (let x = 0; x < GameData.col; x++) {
            for (let y = 0; y < GameData.row; y++) {
                const grid: Grid = CardFunctions.GetGrid(x, y);
                grid.Select(active);
            }
        }
    }

    static GetScore() {
        let score: number = 10;
        return score;
    }

    // 是否存在Grid
    static HasGrid(x: number, y: number): boolean {
        if (GameData.arrGrids[x] && GameData.arrGrids[x][y] && GameData.arrGrids[x][y].id >= 0) {
            return true;
        } else {
            return false;
        }
    }



    // 左下
    static Time1(): Promise<any> {
        const p = new Promise((resolve, refjec) => {
            // setTimeout(() => {
            resolve(0);
            // }, 200);
        })
        return p;
    }

    // 
    static async CheckGrid(grid_0: Grid, blockGroup) {
        let return_list = [];

        let gridPos_0 = cc.v2(grid_0.x, grid_0.y);

        // console.log(`blockGroup.block_list.length`, blockGroup.block_list.length);

        let count = 0;
        for (let index = 0; index < blockGroup.block_list.length; index++) {
            const block_0: Block = blockGroup.block_list[index];
            // console.log(`block_0`, block_0.node.x, block_0.node.y);

            let value = await this.Time1();


            for (let index_2 = 0; index_2 < blockGroup.block_list.length; index_2++) {
                const block_1: Block = blockGroup.block_list[index_2];
                // console.log(`block_1`, block_1.node.x, block_1.node.y);
                let diff = cc.v2(block_1.node.x - block_0.node.x, block_1.node.y - block_0.node.y);
                // console.log(`diff`, diff.x, diff.y);
                let diff_pos = cc.v2(diff.x / 90, diff.y / 90);
                // console.log(`diff_pos`, diff_pos.x, diff_pos.y);
                let gridPos_1 = cc.v2(gridPos_0.x + diff_pos.x, gridPos_0.y + diff_pos.y);
                const grid1: Grid = CardFunctions.GetGrid(gridPos_1.x, gridPos_1.y);
                if (grid1) {
                    if (grid1.block === null) {
                        return_list.push(grid1);
                        if (return_list.length >= blockGroup.block_list.length) {
                            console.log(`return_list`, return_list);
                            return return_list;
                        }

                    }
                    else {
                        return [];
                    }
                }
                else {
                    return [];
                }
            }

            // if (count >= blockGroup.block_list.length - 1) {
            //     const p = new Promise((resolve, refjec) => {
            //         resolve(0);
            //     })
            //     return p;
            // }
            count++;
        }
        // }

        return return_list;
    }

    /**  */
    static ChenckIsDead() {
        // let list = [];

        // for (let index_0 = 0; index_0 < GamePanel.Instance.GeneratePoint_blook_list.length; index_0++) {
        //     let node = GamePanel.Instance.GeneratePoint_blook_list[index_0];
        //     // console.log(`ChenckIsDead-node`, node);
        //     let blockGroup: BlockGroup = GamePanel.Instance.GeneratePoint_blook_list[index_0].getComponentsInChildren(BlockGroup)[0];

        //     // let blockGroup: Block = GamePanel.Instance.GeneratePoint_blook_list[index_0].getComponentsInChildren(Block)[0];
        //     // console.log(`ChenckIsDead-block_target`, blockGroup);

        //     // blockGroup.node.scale = 0.6;

        //     // CardFunctions.SetAllGridCanPlaceForce(true);
        //     // CardFunctions.SetAllGridCanPlaceByBlock(blockGroup);

        //     // CardFunctions.RefreshAllGridCanPlace();

        //     let getCanPlceTrueGridList = CardFunctions.GetCanPlceTrueGridList();
        //     // console.log(`getCanPlceTrueGridList`, getCanPlceTrueGridList.length, getCanPlceTrueGridList);

        //     list = list.concat(getCanPlceTrueGridList);
        // }

        // return list;
    }

    public static Get_array_all_card_type() {
        // const card_count = GameData.MapData_CurrentLevel.length;//牌的总数
        // let card_type_arr = GameData.Card_types;//种类

        // let en = GameData.CurrentLevelDataList[GameData.CurrentLevel].en;
        // let item = GameData.Card_types.find(x => x === en)
        // console.log(`item----------`, item);


        // let 变化 = false;
        // let count = 0;
        // let index_card_type_arr = 0;
        // let array_all_card_type = [];
        // for (let index = 0; index < card_count; index++) {

        //     if (变化) {
        //         // let card_type = card_type_arr[0];
        //         array_all_card_type.push(en);
        //     }
        //     else {
        //         let card_type = card_type_arr[index_card_type_arr];
        //         array_all_card_type.push(card_type);
        //     }

        //     count++;
        //     if (count >= 3) {
        //         count = 0;
        //         index_card_type_arr++;
        //         if (index_card_type_arr > card_type_arr.length - 1) {
        //             index_card_type_arr = 0;
        //         }

        //         if (array_all_card_type.length >= card_count * 0.6) {
        //             变化 = true;
        //         }
        //     }
        // }
        // // console.log(`array_all_card_type`, array_all_card_type);

        // return array_all_card_type;
    }

    // 初始化打乱顺序
    public static Shuffle_MapData_CurrentLevel() {
        // let array_all_card_type = CardFunctions.Get_array_all_card_type()
        // ArrayUtils.Shuffle(array_all_card_type);
        // for (let index = 0; index < GameData.MapData_CurrentLevel.length; index++) {
        //     const element = GameData.MapData_CurrentLevel[index];
        //     const card_type = array_all_card_type[index];
        //     element.card_type = card_type;
        // }
    }

    // // 刷新当前卡片是否被覆盖
    // public static GetCardCover(itemdata: any, dataList: any[]) {
    //     let isCover: boolean = false;

    //     for (var i_2 = 0; i_2 <= dataList.length - 1; i_2++) {
    //         const itemdata_up: any = dataList[i_2];
    //         const pos_1 = itemdata.card_pos;
    //         const pos_2 = itemdata_up.card_pos;
    //         // if (!itemdata_up.isOperate && itemdata_up.card_layer > itemdata.card_layer) {
    //         // itemdata.cardGameState = CardGameState.空地;

    //         // console.log("itemdata_up.cardGameState", itemdata_up.cardGameState);

    //         if (itemdata_up.cardGameState === CardGameState.游戏场景 && itemdata_up.card_layer > itemdata.card_layer) {
    //             // let t1: boolean = pos_1.x === pos_2.x && Math.abs(pos_1.y - pos_2.y) < 1;
    //             // let t2: boolean = pos_1.y === pos_2.y && Math.abs(pos_1.x - pos_2.x) < 1;
    //             // let t3: boolean = Math.pow(pos_1.x - pos_2.x, 2) + Math.pow((pos_1.y - pos_2.y), 2) < 2;
    //             // if (t1 || t2 || t3) {
    //             // if ((pos_1.x === pos_2.x && Math.abs(pos_1.y - pos_2.y) < 1) ||
    //             //     (pos_1.y === pos_2.y && Math.abs(pos_1.x - pos_2.x) < 1) ||
    //             //     (Math.pow(pos_1.x - pos_2.x, 2) + Math.pow((pos_1.y - pos_2.y), 2) < 2)) {
    //             const isBanana = CardFunctions.IsBanana(pos_1, pos_2);
    //             if (isBanana) {
    //                 return true;
    //                 // isCover = true;
    //                 // break;
    //             }
    //             // }
    //         }
    //     }

    //     return isCover;
    // }

    // public static IsBanana(pos_1: cc.Vec2, pos_2: cc.Vec2): boolean {
    //     if (Math.abs(pos_1.x - pos_2.x) < 1 && Math.abs(pos_1.y - pos_2.y) < 1) return true;
    //     return false;
    // }



    // 获取比指定Board层高的
    public static GetHighLayerBoardArray(_board: Board) {
        const array = [];
        for (let index = 0; index < GameData.arrBoard.length; index++) {
            const board = GameData.arrBoard[index];
            if (board.layer > _board.layer) {
                array.push(board);
            }
        }

        // console.log("array", array);

        return array;
    }

    // 指定Board是否被遮挡
    public static IsBoardCover(_board: Board) {
        const array = CardFunctions.GetHighLayerBoardArray(_board);
        for (let index = 0; index < array.length; index++) {
            const board = array[index];
            if (_board !== board) {
                let isBanana = CardFunctions.IsBanana(_board, board);
                if (isBanana) {
                    return true;
                }
            }
        }

        return false;
    }

    // 是否相交
    public static IsBanana(b1: Board, b2: Board): boolean {
        let w = (b1.w + b2.w) * 0.5;
        let h = (b1.h + b2.h) * 0.5;
        let x = Math.abs(b1.node.position.x - b2.node.position.x);
        let y = Math.abs(b1.node.position.y - b2.node.position.y);

        // console.log("w", w);
        // console.log("h", h);
        // console.log("x", x);
        // console.log("y", y);
        // console.log("b1.x.y", b1.node.x, b1.node.y);
        // console.log("b2.x.y", b2.node.x, b2.node.y);
        // console.log("b1===b2", b1 === b2);
        // console.log("b1.x.y", b1.node.position.x);

        // if (CommonFunction.checkIntersectOrContain(b1.collider, b2.collider)) {
        // if (CommonFunction.checkIntersectOrContainByBoundingBox(b1.collider, b2.collider)) {
        if (x < w && y < h) {
            return true;
        }

        return false;
    }

    // 设置所有卡片覆盖
    public static SetAllBoardCover() {
        for (let index = 0; index < GameData.arrBoard.length; index++) {
            const board = GameData.arrBoard[index];
            board.SetCover();
        }
    }

    // 
    public static GetAllItemArray() {
        let array = [];

        let data_up = GameData.Get_LevelData_up();
        for (let index = 0; index < data_up.length; index++) {
            let data_layer = data_up[index];
            for (let _layer = 0; _layer < data_layer.length; _layer++) {
                const item_data_c = data_layer[_layer].c;
                // console.log("item_data_c", item_data_c);

                for (let index = 0; index < item_data_c.length; index++) {
                    const id = item_data_c[index];
                    if (id >= 0) {
                        const find_item = array.find(element => element.id === id);
                        if (find_item) {
                            find_item.count++;
                        }
                        else {
                            let item = { id: id, count: 1 };
                            array.push(item);
                        }
                    }
                }
            }
        }

        // console.log("GetAllItemArray", array);

        return array;
    }

    // 
    public static 生成id俄罗斯方块(_count) {
        let arr = [];

        while (_count > 0) {
            const array = CardFunctions.Get_tetrisCountArray_less(_count);
            // console.log("生成id俄罗斯方块", array);

            let random = randomRangeInt(0, array.length);
            let item = array[random];
            let count = item.count;
            arr.push(item);
            _count -= count;
        }

        // console.log("生成id俄罗斯方块-arr", arr);

        return arr;
    }

    // 
    public static GetAllBlockGroup() {
        // let array = [];

        let array = CardFunctions.GetAllItemArray();

        for (let index = 0; index < array.length; index++) {
            const item = array[index];
            console.log("item", item);

            let arr = CardFunctions.生成id俄罗斯方块(item.count);
            console.log(arr);

            for (let index = 0; index < arr.length; index++) {
                const element = arr[index];
                GameData.currentLevelData_d.push({
                    t: element.tetris_id,
                    c: item.id,
                });
            }

        }

        console.log("GameData.currentLevelData_d", GameData.currentLevelData_d);

        return array;
    }

    // 获取方块的数量
    public static Get_tetrisCount(_id) {
        const item = GameData.TetrisData.find(e => e.tetris_id === _id);
        if (item) {
            return item.count;
        }

        return 0;
    }

    // 获取方块的数量=count的方块数组
    public static Get_tetrisCountArray(_count) {
        const array = GameData.TetrisData.filter(e => e.count === _count);
        if (array && array.length && array.length > 0) {
            return array;
        }

        return [];
    }

    // 获取方块的数量<=count的方块数组
    public static Get_tetrisCountArray_less(_count) {
        const array = GameData.TetrisData.filter(e => e.count <= _count);
        if (array && array.length && array.length > 0) {
            return array;
        }

        return [];
    }

    // // 刷新所有卡片覆盖
    // public static RefreshAllCardCover(dataList: any[]) {
    //     for (let index = 0; index < GameData.arrBoard.length; index++) {
    //         const board = GameData.arrBoard[index];
    //         board.RefreshCover();
    //     }

    //     // console.log(`dataList`, dataList);
    //     // console.log("GameData.arrBoard", GameData.arrBoard);

    //     // for (var i = 0; i <= dataList.length - 1; i++) {
    //     //     const itemdata: any = dataList[i];
    //     //     let isCover = CardFunctions.GetCardCover(itemdata, dataList);
    //     //     let card: Card = GameData.arrCards[i];
    //     //     card.isCover = isCover;
    //     //     // console.log("card.isCover", card.isCover);

    //     //     card.Refresh();
    //     // }
    // }

}

/** 调试 */
window["CardFunctions"] = CardFunctions;